<!doctype html><html lang="en">
 <head>
  <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  <title>Paint Timing 1</title>
  <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
  <meta content="ED" name="w3c-status">
  <link href="https://www.w3.org/StyleSheets/TR/2016/W3C-ED" rel="stylesheet" type="text/css">
  <link href="https://www.w3.org/TR/paint-timing/" rel="canonical">
<style>/* style-md-lists */

/* This is a weird hack for me not yet following the commonmark spec
   regarding paragraph and lists. */
[data-md] > :first-child {
    margin-top: 0;
}
[data-md] > :last-child {
    margin-bottom: 0;
}</style>
<style>/* style-selflinks */

.heading, .issue, .note, .example, li, dt {
    position: relative;
}
a.self-link {
    position: absolute;
    top: 0;
    left: calc(-1 * (3.5rem - 26px));
    width: calc(3.5rem - 26px);
    height: 2em;
    text-align: center;
    border: none;
    transition: opacity .2s;
    opacity: .5;
}
a.self-link:hover {
    opacity: 1;
}
.heading > a.self-link {
    font-size: 83%;
}
li > a.self-link {
    left: calc(-1 * (3.5rem - 26px) - 2em);
}
dfn > a.self-link {
    top: auto;
    left: auto;
    opacity: 0;
    width: 1.5em;
    height: 1.5em;
    background: gray;
    color: white;
    font-style: normal;
    transition: opacity .2s, background-color .2s, color .2s;
}
dfn:hover > a.self-link {
    opacity: 1;
}
dfn > a.self-link:hover {
    color: black;
}

a.self-link::before            { content: "¶"; }
.heading > a.self-link::before { content: "§"; }
dfn > a.self-link::before      { content: "#"; }</style>
<style>/* style-counters */

body {
    counter-reset: example figure issue;
}
.issue {
    counter-increment: issue;
}
.issue:not(.no-marker)::before {
    content: "Issue " counter(issue);
}

.example {
    counter-increment: example;
}
.example:not(.no-marker)::before {
    content: "Example " counter(example);
}
.invalid.example:not(.no-marker)::before,
.illegal.example:not(.no-marker)::before {
    content: "Invalid Example" counter(example);
}

figcaption {
    counter-increment: figure;
}
figcaption:not(.no-marker)::before {
    content: "Figure " counter(figure) " ";
}</style>
<style>/* style-var-click-highlighting */

    var { cursor: pointer; }
    var.selected0 { background-color: #F4D200; box-shadow: 0 0 0 2px #F4D200; }
    var.selected1 { background-color: #FF87A2; box-shadow: 0 0 0 2px #FF87A2; }
    var.selected2 { background-color: #96E885; box-shadow: 0 0 0 2px #96E885; }
    var.selected3 { background-color: #3EEED2; box-shadow: 0 0 0 2px #3EEED2; }
    var.selected4 { background-color: #EACFB6; box-shadow: 0 0 0 2px #EACFB6; }
    var.selected5 { background-color: #82DDFF; box-shadow: 0 0 0 2px #82DDFF; }
    var.selected6 { background-color: #FFBCF2; box-shadow: 0 0 0 2px #FFBCF2; }
    </style>
<style>/* style-autolinks */

.css.css, .property.property, .descriptor.descriptor {
    color: #005a9c;
    font-size: inherit;
    font-family: inherit;
}
.css::before, .property::before, .descriptor::before {
    content: "‘";
}
.css::after, .property::after, .descriptor::after {
    content: "’";
}
.property, .descriptor {
    /* Don't wrap property and descriptor names */
    white-space: nowrap;
}
.type { /* CSS value <type> */
    font-style: italic;
}
pre .property::before, pre .property::after {
    content: "";
}
[data-link-type="property"]::before,
[data-link-type="propdesc"]::before,
[data-link-type="descriptor"]::before,
[data-link-type="value"]::before,
[data-link-type="function"]::before,
[data-link-type="at-rule"]::before,
[data-link-type="selector"]::before,
[data-link-type="maybe"]::before {
    content: "‘";
}
[data-link-type="property"]::after,
[data-link-type="propdesc"]::after,
[data-link-type="descriptor"]::after,
[data-link-type="value"]::after,
[data-link-type="function"]::after,
[data-link-type="at-rule"]::after,
[data-link-type="selector"]::after,
[data-link-type="maybe"]::after {
    content: "’";
}

[data-link-type].production::before,
[data-link-type].production::after,
.prod [data-link-type]::before,
.prod [data-link-type]::after {
    content: "";
}

[data-link-type=element],
[data-link-type=element-attr] {
    font-family: Menlo, Consolas, "DejaVu Sans Mono", monospace;
    font-size: .9em;
}
[data-link-type=element]::before { content: "<" }
[data-link-type=element]::after  { content: ">" }

[data-link-type=biblio] {
    white-space: pre;
}</style>
<style>/* style-dfn-panel */

.dfn-panel {
    position: absolute;
    z-index: 35;
    height: auto;
    width: -webkit-fit-content;
    width: fit-content;
    max-width: 300px;
    max-height: 500px;
    overflow: auto;
    padding: 0.5em 0.75em;
    font: small Helvetica Neue, sans-serif, Droid Sans Fallback;
    background: #DDDDDD;
    color: black;
    border: outset 0.2em;
}
.dfn-panel:not(.on) { display: none; }
.dfn-panel * { margin: 0; padding: 0; text-indent: 0; }
.dfn-panel > b { display: block; }
.dfn-panel a { color: black; }
.dfn-panel a:not(:hover) { text-decoration: none !important; border-bottom: none !important; }
.dfn-panel > b + b { margin-top: 0.25em; }
.dfn-panel ul { padding: 0; }
.dfn-panel li { list-style: inside; }
.dfn-panel.activated {
    display: inline-block;
    position: fixed;
    left: .5em;
    bottom: 2em;
    margin: 0 auto;
    max-width: calc(100vw - 1.5em - .4em - .5em);
    max-height: 30vh;
}

.dfn-paneled { cursor: pointer; }
</style>
<style>/* style-syntax-highlighting */
pre.idl.highlight { color: #708090; }
.highlight:not(.idl) { background: hsl(24, 20%, 95%); }
code.highlight { padding: .1em; border-radius: .3em; }
pre.highlight, pre > code.highlight { display: block; padding: 1em; margin: .5em 0; overflow: auto; border-radius: 0; }
c-[a] { color: #990055 } /* Keyword.Declaration */
c-[b] { color: #990055 } /* Keyword.Type */
c-[c] { color: #708090 } /* Comment */
c-[d] { color: #708090 } /* Comment.Multiline */
c-[e] { color: #0077aa } /* Name.Attribute */
c-[f] { color: #669900 } /* Name.Tag */
c-[g] { color: #222222 } /* Name.Variable */
c-[k] { color: #990055 } /* Keyword */
c-[l] { color: #000000 } /* Literal */
c-[m] { color: #000000 } /* Literal.Number */
c-[n] { color: #0077aa } /* Name */
c-[o] { color: #999999 } /* Operator */
c-[p] { color: #999999 } /* Punctuation */
c-[s] { color: #a67f59 } /* Literal.String */
c-[t] { color: #a67f59 } /* Literal.String.Single */
c-[u] { color: #a67f59 } /* Literal.String.Double */
c-[cp] { color: #708090 } /* Comment.Preproc */
c-[c1] { color: #708090 } /* Comment.Single */
c-[cs] { color: #708090 } /* Comment.Special */
c-[kc] { color: #990055 } /* Keyword.Constant */
c-[kn] { color: #990055 } /* Keyword.Namespace */
c-[kp] { color: #990055 } /* Keyword.Pseudo */
c-[kr] { color: #990055 } /* Keyword.Reserved */
c-[ld] { color: #000000 } /* Literal.Date */
c-[nc] { color: #0077aa } /* Name.Class */
c-[no] { color: #0077aa } /* Name.Constant */
c-[nd] { color: #0077aa } /* Name.Decorator */
c-[ni] { color: #0077aa } /* Name.Entity */
c-[ne] { color: #0077aa } /* Name.Exception */
c-[nf] { color: #0077aa } /* Name.Function */
c-[nl] { color: #0077aa } /* Name.Label */
c-[nn] { color: #0077aa } /* Name.Namespace */
c-[py] { color: #0077aa } /* Name.Property */
c-[ow] { color: #999999 } /* Operator.Word */
c-[mb] { color: #000000 } /* Literal.Number.Bin */
c-[mf] { color: #000000 } /* Literal.Number.Float */
c-[mh] { color: #000000 } /* Literal.Number.Hex */
c-[mi] { color: #000000 } /* Literal.Number.Integer */
c-[mo] { color: #000000 } /* Literal.Number.Oct */
c-[sb] { color: #a67f59 } /* Literal.String.Backtick */
c-[sc] { color: #a67f59 } /* Literal.String.Char */
c-[sd] { color: #a67f59 } /* Literal.String.Doc */
c-[se] { color: #a67f59 } /* Literal.String.Escape */
c-[sh] { color: #a67f59 } /* Literal.String.Heredoc */
c-[si] { color: #a67f59 } /* Literal.String.Interpol */
c-[sx] { color: #a67f59 } /* Literal.String.Other */
c-[sr] { color: #a67f59 } /* Literal.String.Regex */
c-[ss] { color: #a67f59 } /* Literal.String.Symbol */
c-[vc] { color: #0077aa } /* Name.Variable.Class */
c-[vg] { color: #0077aa } /* Name.Variable.Global */
c-[vi] { color: #0077aa } /* Name.Variable.Instance */
c-[il] { color: #000000 } /* Literal.Number.Integer.Long */
</style>
 <body class="h-entry">
  <div class="head">
   <header>
    <p data-fill-with="logo"><a href="https://www.w3.org/"><img alt="W3C" height="48" src="https://www.w3.org/StyleSheets/TR/2016/logos/W3C" width="72"></a> </p>
    <h1 class="p-name no-ref" id="title">Paint Timing 1</h1>
    <h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Editor’s Draft, <time class="dt-updated" datetime="1970-01-01">1 January 1970</time></span></h2>
   </header>
   <div data-fill-with="spec-metadata">
    <dl>
     <dt>This version:
     <dd><a class="u-url" href="https://w3c.github.io/paint-timing/">https://w3c.github.io/paint-timing/</a>
     <dt>Latest published version:
     <dd><a href="https://www.w3.org/TR/paint-timing/">https://www.w3.org/TR/paint-timing/</a>
     <dt class="editor">Editor:
     <dd class="editor p-author h-card vcard"><a class="p-name fn u-email email" href="mailto:panicker@google.com">Shubhie Panicker</a> (<a class="p-org org" href="https://google.com">Google</a>)
    </dl>
   </div>
   <div data-fill-with="warning"></div>
   <p class="copyright" data-fill-with="copyright"><a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 1970 <a href="https://www.w3.org/"><abbr title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a href="https://www.csail.mit.edu/"><abbr title="Massachusetts Institute of Technology">MIT</abbr></a>, <a href="https://www.ercim.eu/"><abbr title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>, <a href="https://www.keio.ac.jp/">Keio</a>, <a href="https://ev.buaa.edu.cn/">Beihang</a>). W3C <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>, <a href="https://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a> and <a href="https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document" rel="license">permissive document license</a> rules apply. </p>
   <hr title="Separator for header">
  </div>
  <div class="p-summary" data-fill-with="abstract">
   <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2>
   <p>This document defines an API that can be used to capture a series of key moments (First Paint, First Contentful Paint) during pageload which developers care about.</p>
  </div>
  <h2 class="no-num no-toc no-ref heading settled" id="status"><span class="content">Status of this document</span></h2>
  <div data-fill-with="status">
   <p> <em>This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current <abbr title="World Wide Web Consortium">W3C</abbr> publications and the latest revision of this technical report can be found in the <a href="https://www.w3.org/TR/"><abbr title="World Wide Web Consortium">W3C</abbr> technical reports index</a> at https://www.w3.org/TR/.</em> </p>
   <p> This document was published by the <a href="https://www.w3.org/webperf/">Web Performance Working Group</a> as an Editors Draft. This document is intended to become a W3C Recommendation. </p>
   <p></p>
   <p> Feedback and comments on this specification are welcome, please send them to <a href="mailto:public-web-perf@w3.org?subject=%5Bpaint-timing%5D">public-web-perf@w3.org</a> (<a href="mailto:public-web-perf-request@w3.org?subject=subscribe">subscribe</a>, <a href="https://lists.w3.org/Archives/Public/public-web-perf/">archives</a>) with <code class="highlight"><c- p>[</c->paint<c- o>-</c->timing<c- p>]</c-></code> at the start of your email’s subject. </p>
   <p> Publication as an Editors Draft does not imply endorsement by the <abbr title="World Wide Web Consortium">W3C</abbr> Membership. This is a draft document and may
    be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite
    this document as other than work in progress. </p>
   <p> This document was produced by a group operating under the <a href="https://www.w3.org/Consortium/Patent-Policy/"><abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>. <abbr title="World Wide Web Consortium">W3C</abbr> maintains a <a href="https://www.w3.org/2004/01/pp-impl/45211/status" rel="disclosure">public list of any patent disclosures</a> made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains <a href="https://www.w3.org/Consortium/Patent-Policy/#def-essential">Essential Claim(s)</a> must disclose the information in accordance with <a href="https://www.w3.org/Consortium/Patent-Policy/#sec-Disclosure">section 6 of the <abbr title="World Wide Web Consortium">W3C</abbr> Patent Policy</a>. </p>
   <p>This document is governed by the <a href="https://www.w3.org/2019/Process-20190301/" id="w3c_process_revision">1 March 2019 W3C Process Document</a>. </p>
  </div>
  <div data-fill-with="at-risk"></div>
  <nav data-fill-with="table-of-contents" id="toc">
   <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2>
   <ol class="toc" role="directory">
    <li>
     <a href="#intro"><span class="secno">1</span> <span class="content">Introduction</span></a>
     <ol class="toc">
      <li><a href="#example"><span class="secno">1.1</span> <span class="content">Usage example</span></a>
     </ol>
    <li><a href="#sec-terminology"><span class="secno">2</span> <span class="content">Terminology</span></a>
    <li><a href="#sec-PerformancePaintTiming"><span class="secno">3</span> <span class="content">The <code class="idl"><span>PerformancePaintTiming</span></code> interface</span></a>
    <li>
     <a href="#sec-processing-model"><span class="secno">4</span> <span class="content">Processing model</span></a>
     <ol class="toc">
      <li>
       <a href="#sec-reporting-paint-timing"><span class="secno">4.1</span> <span class="content">Reporting paint timing</span></a>
       <ol class="toc">
        <li><a href="#mark-paint-timing"><span class="secno">4.1.1</span> <span class="content">Mark paint timing</span></a>
        <li><a href="#report-paint-timing"><span class="secno">4.1.2</span> <span class="content">Report paint timing</span></a>
       </ol>
     </ol>
    <li><a href="#acknowledgements"><span class="secno">5</span> <span class="content">Acknowledgements</span></a>
    <li>
     <a href="#index"><span class="secno"></span> <span class="content">Index</span></a>
     <ol class="toc">
      <li><a href="#index-defined-here"><span class="secno"></span> <span class="content">Terms defined by this specification</span></a>
      <li><a href="#index-defined-elsewhere"><span class="secno"></span> <span class="content">Terms defined by reference</span></a>
     </ol>
    <li>
     <a href="#references"><span class="secno"></span> <span class="content">References</span></a>
     <ol class="toc">
      <li><a href="#normative"><span class="secno"></span> <span class="content">Normative References</span></a>
     </ol>
    <li><a href="#idl-index"><span class="secno"></span> <span class="content">IDL Index</span></a>
   </ol>
  </nav>
  <main>
   <h2 class="heading settled" data-level="1" id="intro"><span class="secno">1. </span><span class="content">Introduction</span><a class="self-link" href="#intro"></a></h2>
    Load is not a single moment in time — it’s an experience that no one metric can fully capture. There are multiple moments during the load experience that can affect whether a user perceives it as "fast" or "slow". 
   <p>First Paint (FP) is the first of these key moments, followed by First Contentful Paint (FCP). These metrics mark the points, immediately after navigation, when the browser renders pixels to the screen. This is important to the user because it answers the question: is it happening?</p>
   <p>The primary difference between the two metrics is FP marks the point when the browser renders anything that is visually different from what was on the screen prior to navigation. By contrast, FCP is the point when the browser renders the first bit of content from the DOM, which may be text, an image, SVG, or even a canvas element.</p>
   <h3 class="heading settled" data-level="1.1" id="example"><span class="secno">1.1. </span><span class="content">Usage example</span><a class="self-link" href="#example"></a></h3>
<pre class="example highlight" id="example-a8843108"><a class="self-link" href="#example-a8843108"></a><c- a>var</c-> observer <c- o>=</c-> <c- k>new</c-> PerformanceObserver<c- p>(</c-><c- a>function</c-><c- p>(</c->list<c- p>)</c-> <c- p>{</c->
    <c- a>var</c-> perfEntries <c- o>=</c-> list<c- p>.</c->getEntries<c- p>();</c->
    <c- k>for</c-> <c- p>(</c-><c- a>var</c-> i <c- o>=</c-> <c- mi>0</c-><c- p>;</c-> i <c- o>&lt;</c-> perfEntries<c- p>.</c->length<c- p>;</c-> i<c- o>++</c-><c- p>)</c-> <c- p>{</c->
        <c- c1>// Process entries</c->
        <c- c1>// report back for analytics and monitoring</c->
        <c- c1>// ...</c->
    <c- p>}</c->
<c- p>});</c->

<c- c1>// register observer for paint timing notifications</c->
observer<c- p>.</c->observe<c- p>({</c->entryTypes<c- o>:</c-> <c- p>[</c-><c- u>"paint"</c-><c- p>]});</c->
</pre>
   <h2 class="heading settled" data-level="2" id="sec-terminology"><span class="secno">2. </span><span class="content">Terminology</span><a class="self-link" href="#sec-terminology"></a></h2>
   <p><dfn data-dfn-type="dfn" data-export id="paint">Paint<a class="self-link" href="#paint"></a></dfn>: the browser has performed a "paint" (or "render") when it has converted the render tree to pixels on the screen.
This is formally defined as the when <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering" id="ref-for-update-the-rendering">update the rendering</a> happens in event loop processing.</p>
   <p class="note" role="note"><span>NOTE:</span> The rendering pipeline is very complex, and the timestamp should be the latest timestamp the browser is able to note in this pipeline (best effort). Typically the time at which the frame is submitted to the OS for display is recommended for this API.</p>
   <p><dfn class="dfn-paneled" data-dfn-type="dfn" data-export id="first-paint">First Paint</dfn> entry contains a <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/hr-time-2/#idl-def-domhighrestimestampdomhighrestimestamp" id="ref-for-idl-def-domhighrestimestampdomhighrestimestamp">DOMHighResTimeStamp</a></code> reporting the time when the browser first rendered after navigation. This excludes the default background paint, but includes non-default background paint and the enclosing box of an iframe. This is the first key moment developers care about in page load – when the browser has started to render the page.</p>
   <p><dfn class="dfn-paneled" data-dfn-type="dfn" data-export id="first-contentful-paint">First Contentful Paint</dfn> entry contains a <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/hr-time-2/#idl-def-domhighrestimestampdomhighrestimestamp" id="ref-for-idl-def-domhighrestimestampdomhighrestimestamp①">DOMHighResTimeStamp</a></code> reporting the time when the browser first rendered any text, image (including background images), non-white canvas or SVG. This excludes any content of iframes, but includes text with pending webfonts. This is the first time users could start consuming page content.</p>
   <h2 class="heading settled" data-level="3" id="sec-PerformancePaintTiming"><span class="secno">3. </span><span class="content">The <code class="idl"><a data-link-type="idl" href="#performancepainttiming" id="ref-for-performancepainttiming">PerformancePaintTiming</a></code> interface</span><a class="self-link" href="#sec-PerformancePaintTiming"></a></h2>
<pre class="idl highlight def">[<a class="idl-code" data-link-type="extended-attribute" href="https://heycam.github.io/webidl/#Exposed" id="ref-for-Exposed"><c- g>Exposed</c-></a>=<c- n>Window</c->]
<c- b>interface</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="interface" data-export id="performancepainttiming"><code class="highlight"><c- g>PerformancePaintTiming</c-></code></dfn> : <a class="n" data-link-type="idl-name" href="https://www.w3.org/TR/performance-timeline-2/#the-performanceentry-interface" id="ref-for-the-performanceentry-interface"><c- n>PerformanceEntry</c-></a> {};
</pre>
   <p><code class="idl"><a data-link-type="idl" href="#performancepainttiming" id="ref-for-performancepainttiming①">PerformancePaintTiming</a></code> extends the following attributes of <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#the-performanceentry-interface" id="ref-for-the-performanceentry-interface①">PerformanceEntry</a></code> interface:</p>
   <ul>
    <li data-md>
     <p>The <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-name" id="ref-for-dom-performanceentry-name">name</a></code> attribute must return a <code class="idl"><a data-link-type="idl" href="https://heycam.github.io/webidl/#idl-DOMString" id="ref-for-idl-DOMString">DOMString</a></code> for minimal frame attribution. Possible values of name are:</p>
     <ul>
      <li data-md>
       <p><code class="highlight"><c- u>"first-paint"</c-></code>: for <a data-link-type="dfn" href="#first-paint" id="ref-for-first-paint">First Paint</a></p>
      <li data-md>
       <p><code class="highlight"><c- u>"first-contentful-paint"</c-></code>: for <a data-link-type="dfn" href="#first-contentful-paint" id="ref-for-first-contentful-paint">First Contentful Paint</a></p>
     </ul>
    <li data-md>
     <p>The <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-entrytype" id="ref-for-dom-performanceentry-entrytype">entryType</a></code> attribute must return <code class="highlight"><c- u>"paint"</c-></code>.</p>
    <li data-md>
     <p>The <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-starttime" id="ref-for-dom-performanceentry-starttime">startTime</a></code> attribute must return a <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/hr-time-2/#idl-def-domhighrestimestampdomhighrestimestamp" id="ref-for-idl-def-domhighrestimestampdomhighrestimestamp②">DOMHighResTimeStamp</a></code> of when the paint occured.</p>
    <li data-md>
     <p>The <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-duration" id="ref-for-dom-performanceentry-duration">duration</a></code> attribute must return 0.</p>
   </ul>
   <p class="note" role="note"><span>NOTE:</span> A user agent implementing <code class="idl"><a data-link-type="idl" href="#performancepainttiming" id="ref-for-performancepainttiming②">PerformancePaintTiming</a></code> would need to include <code class="highlight"><c- u>"first-paint"</c-></code> and <code class="highlight"><c- u>"first-contentful-paint"</c-></code> in <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#supportedentrytypes-attribute" id="ref-for-supportedentrytypes-attribute">supportedEntryTypes</a></code> for <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/window-object.html#window" id="ref-for-window">Window</a></code> contexts.
This allows developers to detect support for paint timing.</p>
   <h2 class="heading settled" data-level="4" id="sec-processing-model"><span class="secno">4. </span><span class="content">Processing model</span><a class="self-link" href="#sec-processing-model"></a></h2>
   <h3 class="heading settled" data-level="4.1" id="sec-reporting-paint-timing"><span class="secno">4.1. </span><span class="content">Reporting paint timing</span><a class="self-link" href="#sec-reporting-paint-timing"></a></h3>
   <h4 class="heading settled" data-dfn-type="dfn" data-level="4.1.1" data-lt="Mark paint timing" data-noexport id="mark-paint-timing"><span class="secno">4.1.1. </span><span class="content">Mark paint timing</span><a class="self-link" href="#mark-paint-timing"></a></h4>
   <div class="algorithm" data-algorithm="Mark paint timing">
     Perform the following steps: 
    <ol>
     <li data-md>
      <p>Let <var>paintTimestamp</var> be the input timestamp.</p>
     <li data-md>
      <p>If this instance of <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering" id="ref-for-update-the-rendering①">update the rendering</a> is the <a data-link-type="dfn" href="#first-paint" id="ref-for-first-paint①">first paint</a>, then record the timestamp as <var>paintTimestamp</var> and invoke the <a href="#report-paint-timing" id="ref-for-report-paint-timing">§ 4.1.2 Report paint timing</a> algorithm with two arguments: <code class="highlight"><c- u>"first-paint"</c-></code> and <var>paintTimestamp</var>.</p>
      <p class="note" role="note"><span>NOTE:</span> First paint excludes the default background paint, but includes non-default background paint.</p>
     <li data-md>
      <p>Otherwise, if this instance of <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering" id="ref-for-update-the-rendering②">update the rendering</a> is the <a data-link-type="dfn" href="#first-contentful-paint" id="ref-for-first-contentful-paint①">first contentful paint</a>, then record the timestamp as <var>paintTimestamp</var> and invoke the <a href="#report-paint-timing" id="ref-for-report-paint-timing①">§ 4.1.2 Report paint timing</a> algorithm with two arguments: <code class="highlight"><c- u>"first-contentful-paint"</c-></code> and <var>paintTimestamp</var>.</p>
      <p class="note" role="note"><span>NOTE:</span> This paint must include text, image (including background images), non-white canvas or SVG.</p>
     <li data-md>
      <p>Otherwise, do nothing and return.</p>
      <p class="note" role="note"><span>NOTE:</span> A parent frame should not be aware of the paint events from its child iframes, and vice versa. This means that a frame that contains just iframes will have first paint (due to the enclosing boxes of the iframes) but no first contentful paint.</p>
    </ol>
   </div>
   <h4 class="heading settled dfn-paneled" data-dfn-type="dfn" data-level="4.1.2" data-lt="Report paint timing" data-noexport id="report-paint-timing"><span class="secno">4.1.2. </span><span class="content">Report paint timing</span></h4>
   <div class="algorithm" data-algorithm="Report paint timing">
     Given two arguments <var>paintType</var> and <var>paintTimestamp</var>, perform the following steps: 
    <ol>
     <li data-md>
      <p>Create a new <code class="idl"><a data-link-type="idl" href="#performancepainttiming" id="ref-for-performancepainttiming③">PerformancePaintTiming</a></code> object <var>newEntry</var> and set its attributes as follows:</p>
      <ol>
       <li data-md>
        <p>Set <var>newEntry</var>’s <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-name" id="ref-for-dom-performanceentry-name①">name</a></code> attribute to <var>paintType</var></p>
       <li data-md>
        <p>Set <var>newEntry</var>’s <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-entrytype" id="ref-for-dom-performanceentry-entrytype①">entryType</a></code> attribute to <code class="highlight">paint</code></p>
       <li data-md>
        <p>Set <var>newEntry</var>’s <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-starttime" id="ref-for-dom-performanceentry-starttime①">startTime</a></code> attribute to <var>paintTimestamp</var></p>
       <li data-md>
        <p>Set <var>newEntry</var>’s <code class="idl"><a data-link-type="idl" href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-duration" id="ref-for-dom-performanceentry-duration①">duration</a></code> attribute to 0.</p>
      </ol>
     <li data-md>
      <p><a href="https://w3c.github.io/performance-timeline/#dfn-queue-a-performanceentry">Add the PerformanceEntry</a> <var>newEntry</var> object.</p>
    </ol>
   </div>
   <h2 class="heading settled" data-level="5" id="acknowledgements"><span class="secno">5. </span><span class="content">Acknowledgements</span><a class="self-link" href="#acknowledgements"></a></h2>
   <p>Special thanks to <a href="https://github.com/w3c/paint-timing/graphs/contributors">all the contributors</a> for their technical input and suggestions that led to improvements to this
specification.</p>
  </main>
<script src="https://www.w3.org/scripts/TR/2016/fixup.js"></script>
  <h2 class="no-num no-ref heading settled" id="index"><span class="content">Index</span><a class="self-link" href="#index"></a></h2>
  <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="content">Terms defined by this specification</span><a class="self-link" href="#index-defined-here"></a></h3>
  <ul class="index">
   <li><a href="#first-contentful-paint">First Contentful Paint</a><span>, in §2</span>
   <li><a href="#first-paint">First Paint</a><span>, in §2</span>
   <li><a href="#mark-paint-timing">Mark paint timing</a><span>, in §4.1</span>
   <li><a href="#paint">Paint</a><span>, in §2</span>
   <li><a href="#performancepainttiming">PerformancePaintTiming</a><span>, in §3</span>
   <li><a href="#report-paint-timing">Report paint timing</a><span>, in §4.1.1</span>
  </ul>
  <aside class="dfn-panel" data-for="term-for-idl-def-domhighrestimestampdomhighrestimestamp">
   <a href="https://www.w3.org/TR/hr-time-2/#idl-def-domhighrestimestampdomhighrestimestamp">https://www.w3.org/TR/hr-time-2/#idl-def-domhighrestimestampdomhighrestimestamp</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-idl-def-domhighrestimestampdomhighrestimestamp">2. Terminology</a> <a href="#ref-for-idl-def-domhighrestimestampdomhighrestimestamp①">(2)</a>
    <li><a href="#ref-for-idl-def-domhighrestimestampdomhighrestimestamp②">3. The PerformancePaintTiming interface</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-window">
   <a href="https://html.spec.whatwg.org/multipage/window-object.html#window">https://html.spec.whatwg.org/multipage/window-object.html#window</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-window">3. The PerformancePaintTiming interface</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-update-the-rendering">
   <a href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering">https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-update-the-rendering">2. Terminology</a>
    <li><a href="#ref-for-update-the-rendering①">4.1.1. Mark paint timing</a> <a href="#ref-for-update-the-rendering②">(2)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-the-performanceentry-interface">
   <a href="https://www.w3.org/TR/performance-timeline-2/#the-performanceentry-interface">https://www.w3.org/TR/performance-timeline-2/#the-performanceentry-interface</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-the-performanceentry-interface">3. The PerformancePaintTiming interface</a> <a href="#ref-for-the-performanceentry-interface①">(2)</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dom-performanceentry-duration">
   <a href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-duration">https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-duration</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dom-performanceentry-duration">3. The PerformancePaintTiming interface</a>
    <li><a href="#ref-for-dom-performanceentry-duration①">4.1.2. Report paint timing</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dom-performanceentry-entrytype">
   <a href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-entrytype">https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-entrytype</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dom-performanceentry-entrytype">3. The PerformancePaintTiming interface</a>
    <li><a href="#ref-for-dom-performanceentry-entrytype①">4.1.2. Report paint timing</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dom-performanceentry-name">
   <a href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-name">https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-name</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dom-performanceentry-name">3. The PerformancePaintTiming interface</a>
    <li><a href="#ref-for-dom-performanceentry-name①">4.1.2. Report paint timing</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-dom-performanceentry-starttime">
   <a href="https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-starttime">https://www.w3.org/TR/performance-timeline-2/#dom-performanceentry-starttime</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-dom-performanceentry-starttime">3. The PerformancePaintTiming interface</a>
    <li><a href="#ref-for-dom-performanceentry-starttime①">4.1.2. Report paint timing</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-supportedentrytypes-attribute">
   <a href="https://www.w3.org/TR/performance-timeline-2/#supportedentrytypes-attribute">https://www.w3.org/TR/performance-timeline-2/#supportedentrytypes-attribute</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-supportedentrytypes-attribute">3. The PerformancePaintTiming interface</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-idl-DOMString">
   <a href="https://heycam.github.io/webidl/#idl-DOMString">https://heycam.github.io/webidl/#idl-DOMString</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-idl-DOMString">3. The PerformancePaintTiming interface</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="term-for-Exposed">
   <a href="https://heycam.github.io/webidl/#Exposed">https://heycam.github.io/webidl/#Exposed</a><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-Exposed">3. The PerformancePaintTiming interface</a>
   </ul>
  </aside>
  <h3 class="no-num no-ref heading settled" id="index-defined-elsewhere"><span class="content">Terms defined by reference</span><a class="self-link" href="#index-defined-elsewhere"></a></h3>
  <ul class="index">
   <li>
    <a data-link-type="biblio">[hr-time-2]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-idl-def-domhighrestimestampdomhighrestimestamp" style="color:initial">DOMHighResTimeStamp</span>
    </ul>
   <li>
    <a data-link-type="biblio">[HTML]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-window" style="color:initial">Window</span>
     <li><span class="dfn-paneled" id="term-for-update-the-rendering" style="color:initial">update the rendering</span>
    </ul>
   <li>
    <a data-link-type="biblio">[performance-timeline-2]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-the-performanceentry-interface" style="color:initial">PerformanceEntry</span>
     <li><span class="dfn-paneled" id="term-for-dom-performanceentry-duration" style="color:initial">duration</span>
     <li><span class="dfn-paneled" id="term-for-dom-performanceentry-entrytype" style="color:initial">entryType</span>
     <li><span class="dfn-paneled" id="term-for-dom-performanceentry-name" style="color:initial">name</span>
     <li><span class="dfn-paneled" id="term-for-dom-performanceentry-starttime" style="color:initial">startTime</span>
     <li><span class="dfn-paneled" id="term-for-supportedentrytypes-attribute" style="color:initial">supportedEntryTypes</span>
    </ul>
   <li>
    <a data-link-type="biblio">[WebIDL]</a> defines the following terms:
    <ul>
     <li><span class="dfn-paneled" id="term-for-idl-DOMString" style="color:initial">DOMString</span>
     <li><span class="dfn-paneled" id="term-for-Exposed" style="color:initial">Exposed</span>
    </ul>
  </ul>
  <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2>
  <h3 class="no-num no-ref heading settled" id="normative"><span class="content">Normative References</span><a class="self-link" href="#normative"></a></h3>
  <dl>
   <dt id="biblio-hr-time-2">[HR-TIME-2]
   <dd>Ilya Grigorik; James Simonsen; Jatinder Mann. <a href="https://www.w3.org/TR/hr-time-2/">High Resolution Time Level 2</a>. 1 March 2018. CR. URL: <a href="https://www.w3.org/TR/hr-time-2/">https://www.w3.org/TR/hr-time-2/</a>
   <dt id="biblio-html">[HTML]
   <dd>Anne van Kesteren; et al. <a href="https://html.spec.whatwg.org/multipage/">HTML Standard</a>. Living Standard. URL: <a href="https://html.spec.whatwg.org/multipage/">https://html.spec.whatwg.org/multipage/</a>
   <dt id="biblio-performance-timeline-2">[PERFORMANCE-TIMELINE-2]
   <dd>Ilya Grigorik. <a href="https://www.w3.org/TR/performance-timeline-2/">Performance Timeline Level 2</a>. 23 April 2019. WD. URL: <a href="https://www.w3.org/TR/performance-timeline-2/">https://www.w3.org/TR/performance-timeline-2/</a>
   <dt id="biblio-webidl">[WebIDL]
   <dd>Boris Zbarsky. <a href="https://heycam.github.io/webidl/">Web IDL</a>. 15 December 2016. ED. URL: <a href="https://heycam.github.io/webidl/">https://heycam.github.io/webidl/</a>
  </dl>
  <h2 class="no-num no-ref heading settled" id="idl-index"><span class="content">IDL Index</span><a class="self-link" href="#idl-index"></a></h2>
<pre class="idl highlight def">[<a class="idl-code" data-link-type="extended-attribute" href="https://heycam.github.io/webidl/#Exposed" id="ref-for-Exposed①"><c- g>Exposed</c-></a>=<c- n>Window</c->]
<c- b>interface</c-> <a href="#performancepainttiming"><code class="highlight"><c- g>PerformancePaintTiming</c-></code></a> : <a class="n" data-link-type="idl-name" href="https://www.w3.org/TR/performance-timeline-2/#the-performanceentry-interface" id="ref-for-the-performanceentry-interface②"><c- n>PerformanceEntry</c-></a> {};

</pre>
  <aside class="dfn-panel" data-for="first-paint">
   <b><a href="#first-paint">#first-paint</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-first-paint">3. The PerformancePaintTiming interface</a>
    <li><a href="#ref-for-first-paint①">4.1.1. Mark paint timing</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="first-contentful-paint">
   <b><a href="#first-contentful-paint">#first-contentful-paint</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-first-contentful-paint">3. The PerformancePaintTiming interface</a>
    <li><a href="#ref-for-first-contentful-paint①">4.1.1. Mark paint timing</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="performancepainttiming">
   <b><a href="#performancepainttiming">#performancepainttiming</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-performancepainttiming">3. The PerformancePaintTiming interface</a> <a href="#ref-for-performancepainttiming①">(2)</a> <a href="#ref-for-performancepainttiming②">(3)</a>
    <li><a href="#ref-for-performancepainttiming③">4.1.2. Report paint timing</a>
   </ul>
  </aside>
  <aside class="dfn-panel" data-for="report-paint-timing">
   <b><a href="#report-paint-timing">#report-paint-timing</a></b><b>Referenced in:</b>
   <ul>
    <li><a href="#ref-for-report-paint-timing">4.1.1. Mark paint timing</a> <a href="#ref-for-report-paint-timing">(2)</a>
   </ul>
  </aside>
<script>/* script-var-click-highlighting */

    document.addEventListener("click", e=>{
        if(e.target.nodeName == "VAR") {
            highlightSameAlgoVars(e.target);
        }
    });
    {
        const indexCounts = new Map();
        const indexNames = new Map();
        function highlightSameAlgoVars(v) {
            // Find the algorithm container.
            let algoContainer = null;
            let searchEl = v;
            while(algoContainer == null && searchEl != document.body) {
                searchEl = searchEl.parentNode;
                if(searchEl.hasAttribute("data-algorithm")) {
                    algoContainer = searchEl;
                }
            }

            // Not highlighting document-global vars,
            // too likely to be unrelated.
            if(algoContainer == null) return;

            const algoName = algoContainer.getAttribute("data-algorithm");
            const varName = getVarName(v);
            const addClass = !v.classList.contains("selected");
            let highlightClass = null;
            if(addClass) {
                const index = chooseHighlightIndex(algoName, varName);
                indexCounts.get(algoName)[index] += 1;
                indexNames.set(algoName+"///"+varName, index);
                highlightClass = nameFromIndex(index);
            } else {
                const index = previousHighlightIndex(algoName, varName);
                indexCounts.get(algoName)[index] -= 1;
                highlightClass = nameFromIndex(index);
            }

            // Find all same-name vars, and toggle their class appropriately.
            for(const el of algoContainer.querySelectorAll("var")) {
                if(getVarName(el) == varName) {
                    el.classList.toggle("selected", addClass);
                    el.classList.toggle(highlightClass, addClass);
                }
            }
        }
        function getVarName(el) {
            return el.textContent.replace(/(\s| )+/, " ").trim();
        }
        function chooseHighlightIndex(algoName, varName) {
            let indexes = null;
            if(indexCounts.has(algoName)) {
                indexes = indexCounts.get(algoName);
            } else {
                // 7 classes right now
                indexes = [0,0,0,0,0,0,0];
                indexCounts.set(algoName, indexes);
            }

            // If the element was recently unclicked,
            // *and* that color is still unclaimed,
            // give it back the same color.
            const lastIndex = previousHighlightIndex(algoName, varName);
            if(indexes[lastIndex] === 0) return lastIndex;

            // Find the earliest index with the lowest count.
            const minCount = Math.min.apply(null, indexes);
            let index = null;
            for(var i = 0; i < indexes.length; i++) {
                if(indexes[i] == minCount) {
                    return i;
                }
            }
        }
        function previousHighlightIndex(algoName, varName) {
            return indexNames.get(algoName+"///"+varName);
        }
        function nameFromIndex(index) {
            return "selected" + index;
        }
    }
    </script>
<script>/* script-dfn-panel */

document.body.addEventListener("click", function(e) {
    var queryAll = function(sel) { return [].slice.call(document.querySelectorAll(sel)); }
    // Find the dfn element or panel, if any, that was clicked on.
    var el = e.target;
    var target;
    var hitALink = false;
    while(el.parentElement) {
        if(el.tagName == "A") {
            // Clicking on a link in a <dfn> shouldn't summon the panel
            hitALink = true;
        }
        if(el.classList.contains("dfn-paneled")) {
            target = "dfn";
            break;
        }
        if(el.classList.contains("dfn-panel")) {
            target = "dfn-panel";
            break;
        }
        el = el.parentElement;
    }
    if(target != "dfn-panel") {
        // Turn off any currently "on" or "activated" panels.
        queryAll(".dfn-panel.on, .dfn-panel.activated").forEach(function(el){
            el.classList.remove("on");
            el.classList.remove("activated");
        });
    }
    if(target == "dfn" && !hitALink) {
        // open the panel
        var dfnPanel = document.querySelector(".dfn-panel[data-for='" + el.id + "']");
        if(dfnPanel) {
            dfnPanel.classList.add("on");
            var rect = el.getBoundingClientRect();
            dfnPanel.style.left = window.scrollX + rect.right + 5 + "px";
            dfnPanel.style.top = window.scrollY + rect.top + "px";
            var panelRect = dfnPanel.getBoundingClientRect();
            var panelWidth = panelRect.right - panelRect.left;
            if(panelRect.right > document.body.scrollWidth && (rect.left - (panelWidth + 5)) > 0) {
                // Reposition, because the panel is overflowing
                dfnPanel.style.left = window.scrollX + rect.left - (panelWidth + 5) + "px";
            }
        } else {
            console.log("Couldn't find .dfn-panel[data-for='" + el.id + "']");
        }
    } else if(target == "dfn-panel") {
        // Switch it to "activated" state, which pins it.
        el.classList.add("activated");
        el.style.left = null;
        el.style.top = null;
    }

});
</script>